import { get } from 'lodash-es';
import { Rule, SectionTarget } from '@/types/rule';
import { ResultType, DataSet, ResultInfo, ValidatorType } from '../types';

const pickReportRaw = (reportRaw: Record<string, unknown>, input: unknown, rawPaths?: string[]) => {
  if (!rawPaths?.length) return;
  for (const path of rawPaths) {
    const raw = get(input, path);
    reportRaw[path] = typeof raw === 'object' ? JSON.stringify(raw) : String(raw);
  }
};

export const validateHandler = (dataSet: DataSet, rule: Rule) => {
  const reportRaw: Record<string, unknown> = {};
  // 校验是否满足条件
  const passport = rule?.condition
    ? Object.entries(rule?.condition).every(([key, validatorUnit]) => {
        pickReportRaw(reportRaw, dataSet[key as SectionTarget], validatorUnit.report_raw_path);
        if (validatorUnit?.schema_compiled) {
          validatorUnit?.schema_compiled(dataSet[key as SectionTarget]);
          // 所有条件均通过
          return !validatorUnit?.schema_compiled.errors;
        }
        return true;
      })
    : true;
  if (!passport) return 'Mismatch Condition';

  const errors: ResultInfo[] = [];
  Object.entries(rule?.validator || {}).forEach(([key, validatorUnit]) => {
    pickReportRaw(reportRaw, dataSet[key as SectionTarget], validatorUnit.report_raw_path);
    if (validatorUnit?.schema_compiled) {
      validatorUnit?.schema_compiled(dataSet[key as SectionTarget]);
      if (validatorUnit?.schema_compiled?.errors) {
        const reportInfo = validatorUnit?.schema_compiled?.errors.map((item) => {
          const targatData = JSON.stringify(
            get(
              dataSet[key as SectionTarget],
              item.instancePath.split('/').filter((path) => path !== '')
            ),
            undefined
          );
          const raw = typeof targatData === 'object' ? JSON.stringify(targatData) : String(targatData);

          return {
            ...rule.info,
            ...reportRaw,
            raw,
            log_id: dataSet.log_id,
            type: ResultType.error,
            target: key as SectionTarget,
            validator_type: ValidatorType.JsonSchema,
            error_info: item,
          };
        });
        reportInfo?.length && errors.push(...reportInfo);
      }
    }
  });
  return errors;
};
